using Framework.Core;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

namespace Framework
{
    public class HttpRequestTask : CustomYieldInstruction, IReference
    {
        private static int _serialId = 1;
        public int ID { get; private set; } = -1;
        public string URL { get; private set; }
        public bool Finished { get; private set; }
        public HttpPostType PostType { get; private set; }
        public List<IMultipartFormSection> FormData { get; private set; }
        public Dictionary<string, string> Headers { get; private set; }
        public Action<HttpResult> Callback { get; private set; }
        public int Retry { get; private set; }
        public HttpResult Result { get; private set; }
        public override bool keepWaiting => waiting();

        public bool IsReferenceActive { get; set; }

        private int _finished;
        public void Tick()
        {
            if (_finished < 0)
            {
                if (Result.Finished)
                {
                    _finished = 3;
                }
            }
            else
            {
                _finished--;
                if (_finished <= 0)
                {
                    this.Finished = true;
                }
            }
        }
        private bool waiting()
        {
            if (Result.Finished)
            {
                this.Finished = true;
                return false;
            }
            return true;
        }
        public void Clear()
        {
            ID = -1;
            FormData = null;
            Callback = null;
            if (Result != null)
            {
                Result.Clear();
            }
            PostType = HttpPostType.undefined;
            _finished = -1;
        }
        public HttpRequestTask Set(string url)
        {
            if (ID <= 0)
            {
                ID = _serialId++;
                this.URL = new Uri(url).AbsoluteUri;
                if (Result == null)
                {
                    Result = new HttpResult();
                }
                Result.Clear();
                Result.url = url;
                this.Finished = false;
                _finished = -1;
            }
            return this;
        }
        public HttpRequestTask Set(Action<HttpResult> value)
        {
            this.Callback = value;
            return this;
        }
        public HttpRequestTask SetRetry(int count)
        {
            Retry = count;
            return this;
        }
        public HttpRequestTask AddFormData(IMultipartFormSection value, HttpPostType type)
        {
            AddData(value, type);
            return this;
        }
        public HttpRequestTask AddFormData(string name, string value)
        {
            return AddFormData(new MultipartFormDataSection(name, value), HttpPostType.form);
        }
        public HttpRequestTask AddFileData(byte[] value, string name = "")
        {
            name = "bytes";
            return AddFormData(new MultipartFormFileSection(name, value), HttpPostType.bytes);
        }
        public HttpRequestTask AddUrlData(string name, string value)
        {
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value)) return this;
            AddData(new MultipartFormDataSection(name, value), HttpPostType.url);
            return this;
        }
        public HttpRequestTask AddJsonData(string value)
        {
            if (FormData != null && FormData.Count > 0)
            {
                FormData.RemoveAt(0);
            }
            AddData(new MultipartFormDataSection(value), HttpPostType.json);
            return this;
        }
        public HttpRequestTask AddData(IMultipartFormSection value, HttpPostType type)
        {
            if (PostType != HttpPostType.undefined && PostType != type)
            {
                throw new Exception("post must be " + PostType.ToString());
            }
            PostType = type;
            if (FormData == null)
            {
                FormData = new List<IMultipartFormSection>();
            }
            if (!string.IsNullOrEmpty(value.sectionName) && FormData.Count > 0)
            {
                var len = FormData.Count;
                while (len-- > 0)
                {
                    if (string.IsNullOrEmpty(FormData[len].sectionName)) continue;
                    if (FormData[len].sectionName == value.sectionName)
                    {
                        FormData.RemoveAt(len);
                    }
                }
            }
            FormData.Add(value);
            return this;
        }
        public void AddHeader(string name, string value)
        {
            if (Headers == null)
            {
                Headers = new Dictionary<string, string>();
            }
            if (Headers.ContainsKey(name))
            {
                Headers[name] = value;
            }
            else
            {
                Headers.Add(name, value);
            }
        }

    }
}